package sing.rabbit.direct.consumer.consume;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author xing
 * @date 2022/9/8 7:47
 */
@Component
public class DirectQueueListener3 implements ChannelAwareMessageListener {
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        String content = new String(message.getBody());
        System.out.println("get message: " + content);
        Map<String, Object> headers = message.getMessageProperties().getHeaders();
        System.out.println(headers);

        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        // 参数: deliveryTag, multiple
        // 手动确认
        // 翻译自 Channel 实现类 ChannelIn 注释: Public API - 确认接收到的一个或多个消息。从AMQP.Basic.GetOk或AMQP.Basic.Deliver方法提供deliveryTag，该方法包含接收到的被确认的消息。
        channel.basicAck(deliveryTag,false);

        // -----------------------------------
        // 参数：deliveryTag, multiple, requeue
        // 解释：翻译自 Channel 实现类 ChannelIn 注释: Public API - 拒绝接收的一条或多条消息。从包含被拒绝消息的AMQP.Basic.GetOk或AMQP.Basic.GetOk方法中提供deliveryTag。

        // requeue: 是否重新放回本地队列，注意接收前，
        // 如果设置了 channel.basicQos(int prefetchCount) 参数为 1; 每次只接受一条消息，
        // （这个方式不知道行不行，<strong>没测试</strong>，但是在 container bean 里设置 container.setPrefetchCount(1); 应该没问题，就设置的比较早了，可以生效）
        // 但是你对这条消息做了 nack 和 requeue，那么可能会到之后会卡死 ，
        // 有1条消息，不再接收新消息，但这条新消息刚被你 nack 了 ，不会继续处理新消息，没的处理，队列空空不出来，就卡死了
        // （可能1. 其他消息被处理后它状态改变，2. 队列有多余空间才会被 requeue 并改变状态，\\ 反正就是不行，会卡死）
        // 而如果 qos 不是1，似乎没这个问题

        //channel.basicNack(deliveryTag, false, true);

        // ---------------------------------------------
        // 参数: deliveryTag, requeue
        // 翻译自 Channel 实现类 ChannelIn 注释: Public API - 拒绝一个消息。从包含被拒绝的接收消息的AMQP.Basic.GetOk或AMQP.Basic.Deliver方法提供deliveryTag。
        // channel.basicReject(deliveryTag, true);
    }
}
